#include<stdio.h>
#include<stdlib.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#include<assert.h>
#include<string.h>
#include<unistd.h>

typedef struct MyFILE
{
    int fd;
    char buffer[1024];
    int end;//当前缓冲区的结尾
}MyFILE;

MyFILE* fopen_(const char* path,const char* mode)
{
    assert(path);
    assert(mode);

    MyFILE*fp=NULL;
    if(strcmp(mode,"r")==0)
    {

    }
    else if(strcmp(mode,"r+")==0)
    {

    }
    else if(strcmp(mode,"w")==0)
    {
       int fd=open(path,O_WRONLY|O_TRUNC|O_CREAT,0666);
        if(fd>0)
        {
            fp=(MyFILE*)malloc(sizeof(MyFILE));
            memset(fp,0,sizeof(MyFILE));
            fp->fd=fd;
        }
    }
    else if(strcmp(mode,"w+")==0)
    {

    }
    else if(strcmp(mode,"a")==0)
    {

    }
    else if(strcmp(mode,"a+")==0)
    {

    }
    else 
    {

    }
    return fp;
}

void fputs_(const char*s,MyFILE*fp)
{
    assert(s);
    assert(fp);

    strcpy(fp->buffer+fp->end,s);
    fp->end+=strlen(s);

    //for debug
    printf("%s\n",fp->buffer);

    if(fp->fd==0)
    {
        //标准输入
    }
    else if(fp->fd==1)
    {
        //标准输出
        if(fp->buffer[fp->end-1]=='\n')
        {
            fprintf(stderr,"%s",fp->buffer);
            write(fp->fd,fp->buffer,fp->end);
            fp->end=0;
        }
    }
    else if(fp->fd==2)
    {
        //标准错误
    }
    else
    {
        //其他文件
    }       
}

void fflush_(MyFILE*fp)
{
    assert(fp);

    if(fp->end!=0)
    {
        //将C库缓冲区的内容刷到内核中
        write(fp->fd,fp->buffer,fp->end);
        syncfs(fp->fd);//将数据写入到磁盘
        fp->end=0;
    }
}

void fclose_(MyFILE*fp)
{
    //刷新fp指向的流（使用fflush写入任何缓冲的输出数据），并关闭底层文件
    assert(fp);
    fflush_(fp);
    close(fp->fd);
    free(fp);
}

int main()
{    
    //close(1);
    MyFILE* fp=fopen_("log.txt","w");
    if(fp==NULL)
    {
        printf("fopen_:fail\n");
        return 1;
    }
    
//    fputs_("one fputs_",fp);
//    fputs_("two fputs_",fp);
//    fputs_("three fputs_\n",fp);
//    fputs_("four fputs_\n",fp);


    const char*ss="hello fputs_()";
    fputs_(ss,fp);


    fork();

    fclose_(fp);
    return 0;
}

